import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.SecureClassLoader;

/**
 *
 */
public class MyClassLoader extends SecureClassLoader {

    private static final String className = "Hello";
    private static final String classFileSuffix = ".xlass";
    private static final String methodName = "hello";

    @Override
    public Class<?> findClass(String name) throws ClassNotFoundException {
        if (name != null && name.equals(className)) {
            try {
                String loadName = className + classFileSuffix;
                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                URL resource = classLoader.getResource(loadName);
                byte[] bytes = toByteArray3(resource.getPath());
                for (int i = 0; i < bytes.length; ++i) {
                    bytes[i] = (byte) (255 - bytes[i]);
                }
                Class<?> targetClass = defineClass(className, bytes, 0, bytes.length);
                return targetClass;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }
        }
        return super.loadClass(name);
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        OkHttpTest myClassLoader = new OkHttpTest();
        Class<?> helloXlass = myClassLoader.findClass(className);
        Method hello = helloXlass.getMethod(methodName);
        hello.invoke(helloXlass.newInstance());
    }

    /**
     * 读取文件
     */
    private static byte[] toByteArray3(String filename) throws IOException {
        FileChannel fc = null;
        try {
            fc = new RandomAccessFile(filename, "r").getChannel();
            MappedByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0,
                    fc.size()).load();
            byte[] result = new byte[(int) fc.size()];
            if (byteBuffer.remaining() > 0) {
                byteBuffer.get(result, 0, byteBuffer.remaining());
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                fc.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
